package org.ytor.core.sysapi.dict;

import org.ytor.common.anno.Dict;
import org.ytor.common.classmeta.ClassMetadata;
import org.ytor.common.classmeta.FieldMetadata;
import org.ytor.common.util.Strs;
import org.ytor.common.util.cache.ClassCache;
import org.ytor.common.util.cache.ICache;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;

/**
 * created by yangtong on 2025/5/31 19:55:03
 * <br/>
 * 字典缓存
 */
public class DictCache {
    private final static String PREFIX = "DICT";
    private static ICache cache;

    public static void registerCache(ICache cache) {
        if (DictCache.cache == null) {
            DictCache.cache = cache;
        }
    }

    /**
     * 获取指定类型中标注了字典的字段，以及对应字段的字典项
     * <br>
     * eg：{
     *       "sex_1":"sexCode",
     *       "name_2":"sys_user,id,real_name"
     *     }
     */
    public static <T> Map<String, String> get(Class<T> clazz) {
        //获取原始字符串
        String dictStr = cache.get(clazz);
        if (dictStr == null) {
            dictStr = put(clazz);
        }

        //解析原始字符串成map
        //dictStr表示一个类中配置的字典信息：sex_1:sexDict|name_2:user,id,realName|age_1:ageDict
        String[] dictItems = dictStr.split("\\|");
        Map<String, String> dictMap = new HashMap<>();
        for (String dictItem : dictItems) {
            //kv的合法格式应该是以冒号分隔的键值对
            String[] kv = dictItem.split(":", 2);
            if (kv.length == 2) {
                dictMap.put(kv[0], kv[1]);
            }
        }
        return dictMap;
    }

    /**
     * 获取指定类型中标注了字典的指定字段
     * <br>
     * eg sys_user,id,real_name
     */
    public static <T> String get(Class<T> clazz, String fieldName) {
        //获取原始字符串
        String dictStr = cache.get(clazz);
        if (dictStr == null) {
            dictStr = put(clazz);
        }

        //解析原始字符串成map
        //dictStr表示一个类中配置的字典信息：sex_1:sexDict|name_2:user,id,realName|age_1:ageDict
        String[] dictItems = dictStr.split("\\|");
        for (String dictItem : dictItems) {
            String[] kv = dictItem.split(":", 2);
            if (kv.length == 2) {
                String name = kv[0];
                name = name.substring(0, name.length() - 2);
                if (name.equals(fieldName)) {
                    return kv[1];
                }
            }
        }
        return null;
    }

    /**
     * 存储指定类型中标注字典的字段，并返回解析后的原始字典信息
     * <br/>
     * eg：sex_1:sexDict|name_2:user,id,realName|age_1:ageDict
     */
    public static <T> String put(Class<T> clazz) {
        StringJoiner sj = new StringJoiner("|");
        ClassMetadata<T> classMetadata = ClassCache.get(clazz);
        List<FieldMetadata> fields = classMetadata.getFields(f -> f.hasAnnotation(Dict.class));

        String dictStr;
        for (FieldMetadata field : fields) {
            String name = field.getName();
            Dict dictAnno = field.getAnnotation(Dict.class);

            String table = dictAnno.table();
            String code = dictAnno.code();
            String text = dictAnno.text();

            //系统字典
            if (Strs.isEmpty(table)) {
                name = name + "_1";
                sj.add(name + ":" + code);
            }
            //表字典
            else {
                name = name + "_2";
                sj.add(name + ":" + table + "," + code + "," + text);
            }
        }
        dictStr = sj.toString();
        cache.put(clazz, dictStr);
        return dictStr;
    }

    /**
     * 获取指定字典项的文本
     */
    public static String getDictItemText(String dictCode, String dictItemValue) {
        String key = PREFIX + "::" + dictCode + "::" + dictItemValue;
        return cache.get(key);
    }


    /**
     * 添加指定字典项的文本
     */
    public static void putDictItemText(String dictCode, String dictItemValue, String dictItemText) {
        String key = PREFIX + "::" + dictCode + "::" + dictItemValue;
        cache.put(key, dictItemText);
    }

    /**
     * 使指定字典项的文本失效
     */
    public static void invalidDictItem(String dictCode, String dictItemValue) {
        String key = PREFIX + "::" + dictCode + "::" + dictItemValue;
        cache.remove(key);
    }
}
